package org.jeecg.config.mybatis;

import java.util.ArrayList;
import java.util.List;

import org.jeecg.common.util.oConvertUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;

import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;

/**
 * 单数据源配置（jeecg.datasource.open = false时生效）
 * @Author zhoujf
 *
 */
@Configuration
@MapperScan(value={"org.jeecg.modules.**.mapper*"})
public class MybatisPlusSaasConfig {
    /**
     * tenant_id 字段名
     */
    private static final String TENANT_FIELD_NAME = "tenant_id";
    /**
     * 哪些表需要做多租户 表需要添加一个字段 tenant_id
     */
    private static final List<String> tenantTable = new ArrayList<String>();

    static {
        tenantTable.add("demo");

        //角色、菜单、部门
        tenantTable.add("sys_role");
        tenantTable.add("sys_permission");
        tenantTable.add("sys_depart");
        //消息
        tenantTable.add("sys_sms");
        tenantTable.add("sys_sms_template");
        //定时任务
        tenantTable.add("sys_quartz_job");
        //职务
        tenantTable.add("sys_position");
        //日志
        tenantTable.add("sys_log");
        //编码规则
        tenantTable.add("sys_fill_rule");
        //字典
        tenantTable.add("sys_dict");
        tenantTable.add("sys_dict_item");
        //数据源
        tenantTable.add("sys_data_source");
        tenantTable.add("sys_data_log");
        //校验规则
        tenantTable.add("sys_check_rule");
        //分类
        tenantTable.add("sys_category");
        //系统通告
        tenantTable.add("sys_announcement");
        tenantTable.add("sys_announcement_send");

        //主数据
        tenantTable.add("mdm_code_rule");
        tenantTable.add("mdm_sys_param");
        tenantTable.add("mdm_currency");
        tenantTable.add("mdm_company");
        tenantTable.add("mdm_factory");
        tenantTable.add("crm_customer");
        tenantTable.add("mdm_supply");
        tenantTable.add("mdm_movement_type");
        tenantTable.add("mdm_warehouse");
        tenantTable.add("mdm_storage_location");
        tenantTable.add("mdm_customer");
        tenantTable.add("mdm_customer_contacts");
        tenantTable.add("mdm_material_code_rule");
        tenantTable.add("mdm_sequence");
        tenantTable.add("mdm_process_route");
        tenantTable.add("mdm_process_route_class");
        tenantTable.add("mdm_process_route_detail");
        tenantTable.add("pp_work_order");
        tenantTable.add("pp_work_order_process");
        tenantTable.add("pp_work_order_report");
        tenantTable.add("pp_work_order_req");
        //物料
        tenantTable.add("mdm_material_type");
        tenantTable.add("mdm_unit");
        tenantTable.add("mdm_unit_conversion");
        tenantTable.add("mdm_material");
        tenantTable.add("mdm_material_class");
        tenantTable.add("mdm_material_factory_detail");
        tenantTable.add("mdm_material_finance_detail");
        tenantTable.add("mdm_material_group");
        tenantTable.add("mdm_material_unit_detail");
        tenantTable.add("mdm_product");
        tenantTable.add("mdm_tax_rate");
        tenantTable.add("mdm_work_center");
        tenantTable.add("mdm_material_prop_group");
        tenantTable.add("mdm_material_prop");
        tenantTable.add("mdm_material_prop_value");
        //EBC
        tenantTable.add("sd_sales_order");
        tenantTable.add("sd_sales_order_detail");
        tenantTable.add("sd_dispatch_notice");
        tenantTable.add("sd_dispatch_notice_detail");
        tenantTable.add("sd_dispatch_load");
        tenantTable.add("sd_dispatch_load_detail");
        tenantTable.add("sd_sales_return");
        tenantTable.add("sd_sales_return_detail");
        tenantTable.add("sd_contract");
        tenantTable.add("sd_contract_detail");
        tenantTable.add("mm_purchase_requisition");
        tenantTable.add("mm_purchase_requisition_detail");
        tenantTable.add("mm_purchase_order");
        tenantTable.add("mm_purchase_order_detail");
        tenantTable.add("mm_stock_in_out");
        tenantTable.add("mm_stock_in_out_detail");
        tenantTable.add("mm_stock_init");
        tenantTable.add("mm_stock_init_detail");
        tenantTable.add("mm_stock_transfer");
        tenantTable.add("mm_stock_transfer_detail");
        tenantTable.add("mm_material_stock");
        tenantTable.add("mm_material_picking");
        tenantTable.add("mm_material_picking_detail");
        tenantTable.add("mm_material_picking_ret");
        tenantTable.add("mm_material_picking_ret_detail");
        tenantTable.add("fi_income_type");
        tenantTable.add("fi_expense_type");
        tenantTable.add("fi_settle_type");
        tenantTable.add("fi_settle_account");
        tenantTable.add("fi_ap_original_amount");
        tenantTable.add("fi_ar_original_amount");
        tenantTable.add("fi_payment_voucher");
        tenantTable.add("fi_payment_voucher_detail");
        tenantTable.add("fi_receive_voucher");
        tenantTable.add("fi_receive_voucher_detail");
        tenantTable.add("fi_other_payment");
        tenantTable.add("fi_other_payment_detail");
        tenantTable.add("fi_other_receive");
        tenantTable.add("fi_other_receive_detail");
        tenantTable.add("fi_payment_verify");
        tenantTable.add("fi_payment_verify_detail");
        tenantTable.add("fi_receive_verify");
        tenantTable.add("fi_receive_verify_detail");
        tenantTable.add("quote_project");
        tenantTable.add("quote_fee_base");
        tenantTable.add("quote_fee");
        tenantTable.add("quote_parts");
        tenantTable.add("quote_product");
        tenantTable.add("quote_product_class");
        tenantTable.add("quote_product_detail");
        tenantTable.add("quote_product_fee");

        //crm
        tenantTable.add("crm_bid");
        tenantTable.add("crm_contract");
        tenantTable.add("crm_contract_detail");
        tenantTable.add("crm_project");
        tenantTable.add("crm_project_model");
        tenantTable.add("crm_project_product");
        tenantTable.add("crm_project_stage");
        tenantTable.add("crm_project_stage_task");
        tenantTable.add("crm_project_stage_key");
        tenantTable.add("crm_project_stage_base");
        tenantTable.add("crm_project_stage_task_base");
        tenantTable.add("crm_project_stage_key_base");
        tenantTable.add("crm_bid_bond");
        tenantTable.add("crm_bid_company");
        tenantTable.add("crm_bid_loan");
        tenantTable.add("crm_bid_product");
        tenantTable.add("crm_bids_detail");
        tenantTable.add("crm_bids_record");
        tenantTable.add("crm_business_opportunities");
        tenantTable.add("crm_bids_detail");
        tenantTable.add("crm_bids_record");
        tenantTable.add("crm_business_opportunities");
        tenantTable.add("crm_competitor");
        tenantTable.add("crm_contacts");
        tenantTable.add("crm_customer_relations");
        tenantTable.add("crm_customer_visit");
        tenantTable.add("crm_follow");
        tenantTable.add("crm_invoice_apply");
        tenantTable.add("crm_invoice_detail");
        tenantTable.add("crm_leads");
        tenantTable.add("crm_leads_product");
        tenantTable.add("crm_letter_guarantee_detail");
        tenantTable.add("crm_lg_apply");
        tenantTable.add("crm_quotation");
        tenantTable.add("crm_quotation_item");
        tenantTable.add("crm_reception_require");
        tenantTable.add("crm_return_money");
        tenantTable.add("crm_return_money_plan");
        tenantTable.add("crm_visiting_customer");
    }


    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            @Override
            public Expression getTenantId() {
                String tenant_id = oConvertUtils.getString(TenantContext.getTenant(),"0");
                return new LongValue(tenant_id);
            }

            @Override
            public String getTenantIdColumn(){
                return TENANT_FIELD_NAME;
            }

            // 返回 true 表示不走租户逻辑
            @Override
            public boolean ignoreTable(String tableName) {
                for(String temp: tenantTable){
                    if(temp.equalsIgnoreCase(tableName)){
                        return false;
                    }
                }
                return true;
            }
        }));
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return interceptor;
    }

//    /**
//     * 下个版本会删除，现在为了避免缓存出现问题不得不配置
//     * @return
//     */
//    @Bean
//    public ConfigurationCustomizer configurationCustomizer() {
//        return configuration -> configuration.setUseDeprecatedExecutor(false);
//    }
//    /**
//     * mybatis-plus SQL执行效率插件【生产环境可以关闭】
//     */
//    @Bean
//    public PerformanceInterceptor performanceInterceptor() {
//        return new PerformanceInterceptor();
//    }

}
